/* *
 * --ライセンスについて--
 *
 * 「本ファイルの内容は Mozilla Public License Version 1.1 (「本ライセンス」)
 * の適用を受けます。
 * 本ライセンスに従わない限り本ファイルを使用することはできません。
 * 本ライセンスのコピーは http://www.mozilla.org/MPL/ から入手できます。
 *
 * 本ライセンスに基づき配布されるソフトウェアは、「現状のまま」で配布されるものであり、
 * 明示的か黙示的かを問わず、いかなる種類の保証も行われません。
 * 本ライセンス上の権利および制限を定める具体的な文言は、本ライセンスを参照してください。
 *
 * オリジナルコードおよび初期開発者は、N_H (h.10x64@gmail.com) です。
 *
 * N_H によって作成された部分の著作権表示は次のとおりです。
 *
 * Copyright (C)N_H 2012
 *
 * このファイルの内容は、上記に代えて、
 * GNU General License version2 以降 (以下 GPL とする)、
 * GNU Lesser General Public License Version 2.1 以降 (以下 LGPL とする)、
 * の条件に従って使用することも可能です。
 * この場合、このファイルの使用には上記の条項ではなく GPL または LGPL の条項が適用されます。
 * このファイルの他者による使用を GPL または LGPL の条件によってのみ許可し、
 * MPL による使用を許可したくない対象者は、上記の条項を削除することでその意思を示し、
 * 上記条項を GPL または LGPL で義務付けられている告知およびその他の条項に置き換えてください。
 * 対象者が上記の条項を削除しない場合、
 * 受領者は MPL または GPL または LGPL ライセンスのいずれによってもこのファイルを
 * 使用することができます。」
 *
 * -- License --
 *
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License。You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND、either express or implied。See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *   N_H (h.10x64@gmail.com).
 *
 * Portions created by the Initial Developer are Copyright (C)N_H 2012
 * the Initial Developer。All Rights Reserved.
 *
 * Alternatively、the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL")、or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above。If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL、and not to allow others to
 * use your version of this file under the terms of the MPL、indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL。If you do not delete
 * the provisions above、a recipient may use your version of this file under
 * the terms of any one of the MPL、the GPL or the LGPL.
 *
 * */
package com.magiciansforest.audio.soundrenderer.logic.mmd;

import com.jme3.util.SortUtil;
import java.io.*;
import projectkyoto.mmd.file.*;

/**
 *
 * @author N_H
 */
public class VMD {

    private String filePath;
    private String fileName;
    protected String vmdHeader; // char[30] Vocaloid Motion Data 0002
    protected String vmdModelName; // char[20]
    protected int motionCount;
    protected VMDMotion motionArray[];
    protected int skinCount;
    protected VMDSkin skinArray[];
    protected int cameraMotionCount;
    protected VMDCameraMotion[] cameraMotionArray;
    protected int lightMotionCount;
    protected VMDLightMotion[] lightMotionArray;

    public VMD(File f) throws IOException {
        read(new FileInputStream(f));
        this.fileName = f.getName();
        this.filePath = f.getAbsolutePath();
    }
    
    public String getFileName() {
        return this.fileName;
    }
    
    public String getFilePath() {
        return this.filePath;
    }
    
    public VMDFile toVMDFile() {
        VMDFile ret = new VMDFile();
        
        ret.setMotionArray(motionArray);
        ret.setMotionCount(motionCount);
        ret.setSkinArray(skinArray);
        ret.setSkinCount(skinCount);
        ret.setVmdHeader(vmdHeader);
        ret.setVmdModelName(vmdModelName);
        
        return ret;
    }

    public void read(InputStream is2) throws IOException {
        DataInputStreamLittleEndian is = null;
        try {
            is = new DataInputStreamLittleEndian(new BufferedInputStream(is2));
            vmdHeader = is.readString(30);
            if (!"Vocaloid Motion Data 0002".equals(vmdHeader)) {
                throw new InvalidVMDFileException();
            }

            vmdModelName = is.readString(20);

            motionCount = is.readInt();
            motionArray = new VMDMotion[motionCount];
            for (int i = 0; i < motionCount; i++) {
                motionArray[i] = new VMDMotion(is);
            }

            skinCount = is.readInt();
            skinArray = new VMDSkin[skinCount];
            for (int i = 0; i < skinCount; i++) {
                skinArray[i] = new VMDSkin(is);
            }

            cameraMotionCount = is.readInt();
            cameraMotionArray = new VMDCameraMotion[cameraMotionCount];
            for (int i = 0; i < cameraMotionArray.length; i++) {
                cameraMotionArray[i] = new VMDCameraMotion(is);
            }

            lightMotionCount = is.readInt();
            lightMotionArray = new VMDLightMotion[lightMotionCount];
            for (int i = 0; i < lightMotionArray.length; i++) {
                lightMotionArray[i] = new VMDLightMotion(is);
            }
            
            SortUtil.qsort(motionArray, VMDMotionComparator.getComparator());
            SortUtil.qsort(skinArray, VMDSkinComparator.getComparator());
            SortUtil.qsort(cameraMotionArray, VMDCameraMotionComparator.getComparator());
            SortUtil.qsort(lightMotionArray, VMDLightMotionComparator.getComparator());
        } finally {
            if (is != null) {
                is.close();
            }
        }
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("vmdHeader = ").append(vmdHeader).append("\n");
        sb.append("vmdModelName = ").append(vmdModelName).append("\n");
        sb.append("motionCount = ").append(motionCount).append("\n");
        sb.append("motionArray = {\n");
        for (VMDMotion m : motionArray) {
            sb.append(m).append("\n");
        }
        sb.append("}\n");
        sb.append("skinCount = ").append(skinCount).append("\n");
        sb.append("skinArray = {\n");
        for (VMDSkin skin : skinArray) {
            sb.append(skin).append("\n");
        }
        sb.append("}\n");
        sb.append("cameraMotionCount = ").append(cameraMotionCount).append("\n");
        sb.append("cameraMotionArray = {\n");
        for (VMDCameraMotion camMotion : cameraMotionArray) {
            sb.append(camMotion).append("\n");
        }
        sb.append("}\n");
        sb.append("lightMotionCount = ").append(lightMotionCount).append("\n");
        sb.append("lightMotionArray = {\n");
        for (VMDLightMotion lightMotion : lightMotionArray) {
            sb.append(lightMotion).append("\n");
        }
        sb.append("}\n");
        return sb.toString();
    }

    public VMDMotion[] getMotionArray() {
        return motionArray;
    }

    public void setMotionArray(VMDMotion[] motionArray) {
        this.motionArray = motionArray;
    }

    public int getMotionCount() {
        return motionCount;
    }

    public void setMotionCount(int motionCount) {
        this.motionCount = motionCount;
    }

    public VMDSkin[] getSkinArray() {
        return skinArray;
    }

    public void setSkinArray(VMDSkin[] skinArray) {
        this.skinArray = skinArray;
    }

    public int getSkinCount() {
        return skinCount;
    }

    public void setSkinCount(int skinCount) {
        this.skinCount = skinCount;
    }
    
    public VMDCameraMotion[] getCameraMotionArray() {
        return this.cameraMotionArray;
    }
    
    public void setCameraMotionArray(VMDCameraMotion[] cameraMotionArray) {
        this.cameraMotionArray = cameraMotionArray;
    }
    
    public int getCameraMotionCount() {
        return this.cameraMotionCount;
    }

    public void setCameraMotionCount(int cameraMotionCount) {
        this.cameraMotionCount = cameraMotionCount;
    }

    public VMDLightMotion[] getLightMotionArray() {
        return lightMotionArray;
    }

    public void setLightMotionArray(VMDLightMotion[] lightMotionArray) {
        this.lightMotionArray = lightMotionArray;
    }

    public int getLightMotionCount() {
        return lightMotionCount;
    }

    public void setLightMotionCount(int lightMotionCount) {
        this.lightMotionCount = lightMotionCount;
    }

    public String getVmdHeader() {
        return vmdHeader;
    }

    public void setVmdHeader(String vmdHeader) {
        this.vmdHeader = vmdHeader;
    }

    public String getVmdModelName() {
        return vmdModelName;
    }

    public void setVmdModelName(String vmdModelName) {
        this.vmdModelName = vmdModelName;
    }
}
